#pragma once
#include <vector>
#include <string>
#include <sstream>
#include <iomanip>
#include <stdexcept>
#include <cstdint>
#include <future>
#include <functional>
#include <thread>
#include <chrono>

namespace DeviceCommons {

    // ==================== 枚举定义 ====================
    // 注意：简化版本仅支持V2协议，确保与C#版本V2协议完全兼容
    enum class CRCType : uint8_t { None = 0, CRC8 = 1, CRC16 = 2, CRC32 = 3, CRC64 = 4 };
    enum class TimeStampFormat : uint8_t { MS = 0, S = 1 };
    enum class HeaderValueType : uint8_t { Standard = 0, Extend = 1 };
    enum class Reserve1 : uint8_t { Close = 0, Open = 1 };
    enum class Reserve2 : uint8_t { Close = 0, Open = 1 };
    
    /// <summary>
    /// 状态值类型枚举 - 与C#版本的StateValueTypeEnum完全一致
    /// 确保序列化/反序列化的协议兼容性
    /// </summary>
    enum class StateValueType : uint8_t {
        Float32 = 1,    // 32位浮点数
        Int32 = 2,      // 32位整数
        String = 3,     // 字符串（UTF-8编码）
        Bool = 4,       // 布尔值
        // 注意：跳过值5，与C#版本保持一致（C#版本中没有ShortFloat）
        UInt16 = 6,     // 16位无符号整数
        Int16 = 7,      // 16位有符号整数
        Timestamp = 8,  // 时间戳（64位）
        Binary = 9,     // 二进制数据
        Double = 10     // 64位双精度浮点数
    };

    // ==================== 辅助函数声明 ====================
    std::string toHex(const std::vector<uint8_t>& v);
    void writeBE16(std::vector<uint8_t>& dst, uint16_t v);
    uint16_t crc16_impl(const std::vector<uint8_t>& data);

    // ============ 状态结构 ============
    /// <summary>
    /// 设备状态结构，包含状态ID、类型和值
    /// 提供工厂方法支持所有StateValueType类型
    /// </summary>
    struct State {
        uint8_t sid;                    // 状态唯一标识符
        StateValueType type;            // 状态值类型
        std::vector<uint8_t> value;     // 状态值的字节表示

        /// <summary>
        /// 创建字符串类型状态
        /// </summary>
        static State makeString(uint8_t id, const std::string& str) {
            State s{ id, StateValueType::String, {} };
            if (str.size() > 255) {
                throw std::invalid_argument("String length exceeds maximum (255 bytes)");
            }
            s.value.push_back(static_cast<uint8_t>(str.size()));
            s.value.insert(s.value.end(), str.begin(), str.end());
            return s;
        }

        /// <summary>
        /// 创建32位浮点数状态
        /// </summary>
        static State makeFloat32(uint8_t id, float value) {
            State s{ id, StateValueType::Float32, {} };
            const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value);
            s.value.assign(bytes, bytes + sizeof(float));
            return s;
        }

        /// <summary>
        /// 创建32位整数状态
        /// </summary>
        static State makeInt32(uint8_t id, int32_t value) {
            State s{ id, StateValueType::Int32, {} };
            const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value);
            s.value.assign(bytes, bytes + sizeof(int32_t));
            return s;
        }

        /// <summary>
        /// 创建布尔类型状态
        /// </summary>
        static State makeBool(uint8_t id, bool value) {
            State s{ id, StateValueType::Bool, {} };
            s.value.push_back(value ? 1 : 0);
            return s;
        }

        /// <summary>
        /// 创建16位无符号整数状态
        /// </summary>
        static State makeUInt16(uint8_t id, uint16_t value) {
            State s{ id, StateValueType::UInt16, {} };
            const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value);
            s.value.assign(bytes, bytes + sizeof(uint16_t));
            return s;
        }

        /// <summary>
        /// 创建16位有符号整数状态
        /// </summary>
        static State makeInt16(uint8_t id, int16_t value) {
            State s{ id, StateValueType::Int16, {} };
            const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value);
            s.value.assign(bytes, bytes + sizeof(int16_t));
            return s;
        }

        /// <summary>
        /// 创建时间戳状态（64位无符号整数）
        /// </summary>
        static State makeTimestamp(uint8_t id, uint64_t timestamp) {
            State s{ id, StateValueType::Timestamp, {} };
            const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&timestamp);
            s.value.assign(bytes, bytes + sizeof(uint64_t));
            return s;
        }

        /// <summary>
        /// 创建二进制数据状态
        /// </summary>
        static State makeBinary(uint8_t id, const std::vector<uint8_t>& data) {
            State s{ id, StateValueType::Binary, {} };
            if (data.size() > 65535) {
                throw std::invalid_argument("Binary data size exceeds maximum (65535 bytes)");
            }
            // 二进制数据使用大端序16位长度字段
            uint16_t length = static_cast<uint16_t>(data.size());
            s.value.push_back(static_cast<uint8_t>((length >> 8) & 0xFF)); // 高位
            s.value.push_back(static_cast<uint8_t>(length & 0xFF));        // 低位
            s.value.insert(s.value.end(), data.begin(), data.end());
            return s;
        }

        /// <summary>
        /// 创建64位双精度浮点数状态
        /// </summary>
        static State makeDouble(uint8_t id, double value) {
            State s{ id, StateValueType::Double, {} };
            const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value);
            s.value.assign(bytes, bytes + sizeof(double));
            return s;
        }
    };

    // ============ 读数结构 ============
    /// <summary>
    /// 设备读数结构，包含时间偏移和状态集合
    /// 提供序列化方法用于协议数据传输
    /// </summary>
    struct Reading {
        int16_t timeOffset;             // 读数时间偏移（相对于基准时间）
        std::vector<State> states;      // 读数包含的状态集合

        /// <summary>
        /// 序列化读数对象为字节数组
        /// 格式：时间偏移(2字节,大端序) + 状态数量(1字节) + 状态数据
        /// </summary>
        std::vector<uint8_t> serialize() const {
            std::vector<uint8_t> out;
            
            // 1. 序列化时间偏移（大端序16位）
            writeBE16(out, static_cast<uint16_t>(timeOffset));
            
            // 2. 序列化状态数量
            if (states.size() > 255) {
                throw std::invalid_argument("Too many states in reading (maximum 255)");
            }
            out.push_back(static_cast<uint8_t>(states.size()));
            
            // 3. 序列化所有状态
            for (const auto& st : states) {
                out.push_back(st.sid);                              // 状态ID
                out.push_back(static_cast<uint8_t>(st.type));       // 状态类型
                out.insert(out.end(), st.value.begin(), st.value.end()); // 状态值
            }
            return out;
        }
    };

    // ============ 设备信息结构 ============
    /// <summary>
    /// 设备信息结构，包含设备ID、类型和读数集合
    /// 提供序列化方法用于协议数据传输
    /// </summary>
    struct DeviceInfo {
        std::string did;                // 设备唯一标识符
        uint8_t deviceType;             // 设备类型编码
        std::vector<Reading> readings;  // 设备包含的读数集合

        /// <summary>
        /// 序列化设备信息为字节数组
        /// 格式：DID长度(1字节) + DID字符串 + 设备类型(1字节) + 读数数量(1字节) + 读数数据
        /// </summary>
        std::vector<uint8_t> serialize() const {
            std::vector<uint8_t> out;
            
            // 1. 序列化设备ID长度和内容
            if (did.size() > 255) {
                throw std::invalid_argument("Device ID length exceeds maximum (255 bytes)");
            }
            out.push_back(static_cast<uint8_t>(did.size()));
            out.insert(out.end(), did.begin(), did.end());
            
            // 2. 序列化设备类型
            out.push_back(deviceType);
            
            // 3. 序列化读数数量和内容
            if (readings.size() > 255) {
                throw std::invalid_argument("Too many readings in device (maximum 255)");
            }
            out.push_back(static_cast<uint8_t>(readings.size()));
            
            // 4. 序列化所有读数
            for (const auto& r : readings) {
                auto sr = r.serialize();
                out.insert(out.end(), sr.begin(), sr.end());
            }
            return out;
        }
    };



    // ==================== 设备消息构建器（简化版） ====================
    /// <summary>
    /// 设备消息构建器类（仅支持V2协议）
    /// 提供简化的链式API用于构建设备消息
    /// 确保与C#版本的V2协议完全兼容
    /// </summary>
    class DeviceMessageBuilder {
        // 简化版固定使用V2协议参数
        static constexpr uint8_t PROTOCOL_VERSION = 0x02;  // 固定V2协议版本
        CRCType crcType_ = CRCType::CRC16;
        TimeStampFormat tsFormat_ = TimeStampFormat::MS;
        HeaderValueType valueType_ = HeaderValueType::Standard;
        Reserve1 reserve1_ = Reserve1::Close;
        Reserve2 reserve2_ = Reserve2::Close;

        DeviceInfo mainDevice_;         // 主设备信息
        std::vector<DeviceInfo> children_;  // 子设备集合

    public:
        /// <summary>
        /// 创建新的构建器实例（静态工厂方法）
        /// </summary>
        static DeviceMessageBuilder create() {
            return DeviceMessageBuilder{};
        }

        // ==================== 简化配置方法 ====================
        /// <summary>
        /// 设置CRC校验类型
        /// </summary>
        DeviceMessageBuilder& withCRC(CRCType c) { crcType_ = c; return *this; }
        
        /// <summary>
        /// 设置时间戳格式
        /// </summary>
        DeviceMessageBuilder& withTimeStampFormat(TimeStampFormat ts) { tsFormat_ = ts; return *this; }
        
        /// <summary>
        /// 设置头部值类型
        /// </summary>
        DeviceMessageBuilder& withHeaderValueType(HeaderValueType vt) { valueType_ = vt; return *this; }

        /// <summary>
        /// 设置完整头部配置（简化版，固定使用V2协议）
        /// </summary>
        DeviceMessageBuilder& withHeader(
            CRCType crcType = CRCType::CRC16,
            TimeStampFormat timeFormat = TimeStampFormat::MS,
            HeaderValueType valueType = HeaderValueType::Standard) {
            
            crcType_ = crcType;
            tsFormat_ = timeFormat;
            valueType_ = valueType;
            return *this;
        }

        // ==================== 设备配置方法 ====================
        /// <summary>
        /// 设置主设备信息
        /// </summary>
        DeviceMessageBuilder& withMainDevice(const std::string& did, uint8_t type,
            std::vector<Reading> readings = {}) {
            if (did.empty()) {
                throw std::invalid_argument("Device ID cannot be empty");
            }
            mainDevice_ = DeviceInfo{ did, type, std::move(readings) };
            return *this;
        }

        /// <summary>
        /// 添加子设备（与C#版本的WithChildDevice方法类似）
        /// </summary>
        DeviceMessageBuilder& addChild(const std::string& did, uint8_t type,
            std::vector<Reading> readings = {}) {
            if (did.empty()) {
                throw std::invalid_argument("Device ID cannot be empty");
            }
            children_.push_back(DeviceInfo{ did, type, std::move(readings) });
            return *this;
        }

        /// <summary>
        /// 为C#版本兼容性提供的别名方法
        /// </summary>
        DeviceMessageBuilder& withChildDevice(const std::string& did, uint8_t type,
            std::vector<Reading> readings = {}) {
            return addChild(did, type, std::move(readings));
        }

        // ==================== 状态添加方法（为C#版本兼容） ====================
        /// <summary>
        /// 为当前设备添加读数和状态（类似C#版本的AddReading方法）
        /// </summary>
        DeviceMessageBuilder& addReading(int16_t timeOffset, const std::vector<State>& states) {
            if (mainDevice_.did.empty()) {
                throw std::invalid_argument("Main device must be set before adding readings");
            }
            Reading reading{ timeOffset, states };
            mainDevice_.readings.push_back(std::move(reading));
            return *this;
        }

        /// <summary>
        /// 为当前设备添加单个状态的读数
        /// </summary>
        DeviceMessageBuilder& addReading(int16_t timeOffset, const State& state) {
            return addReading(timeOffset, std::vector<State>{ state });
        }

        // ==================== 构建方法（简化版） ====================
        /// <summary>
        /// 构建字节数组格式的设备消息（固定使用V2协议）
        /// </summary>
        std::vector<uint8_t> buildBytes() const;

        /// <summary>
        /// 构建十六进制字符串格式的设备消息
        /// </summary>
        std::string buildHex() const;

    private:
        // ==================== V2协议序列化 ====================
        std::vector<uint8_t> buildBytesV2() const;
        void appendCRC(std::vector<uint8_t>& data) const;


    public:
        // ==================== 异步方法 ====================
        /// <summary>
        /// 异步构建字节数组，使用std::future模式
        /// 适用于需要在后台线程处理复杂消息的场景
        /// </summary>
        std::future<std::vector<uint8_t>> buildBytesAsync() const;
        
        /// <summary>
        /// 异步构建十六进制字符串，使用std::future模式
        /// 适用于需要在后台线程处理复杂消息的场景
        /// </summary>
        std::future<std::string> buildHexAsync() const;
        
        // Callback-based async methods for better performance
        template<typename Callback>
        void buildBytesAsync(Callback&& callback) const {
            std::thread([this, callback = std::forward<Callback>(callback)]() {
                try {
                    auto result = buildBytes();
                    callback(std::move(result), std::exception_ptr{});
                } catch (...) {
                    callback(std::vector<uint8_t>{}, std::current_exception());
                }
            }).detach();
        }
        
        template<typename Callback>
        void buildHexAsync(Callback&& callback) const {
            std::thread([this, callback = std::forward<Callback>(callback)]() {
                try {
                    auto result = buildHex();
                    callback(std::move(result), std::exception_ptr{});
                } catch (...) {
                    callback(std::string{}, std::current_exception());
                }
            }).detach();
        }
        
        // Convenience method with timeout support
        template<typename Rep, typename Period>
        std::vector<uint8_t> buildBytesAsyncWait(
            const std::chrono::duration<Rep, Period>& timeout = std::chrono::seconds(5)) const {
            
            auto future = buildBytesAsync();
            if (future.wait_for(timeout) == std::future_status::timeout) {
                throw std::runtime_error("Build bytes operation timed out");
            }
            return future.get();
        }
        
        template<typename Rep, typename Period>
        std::string buildHexAsyncWait(
            const std::chrono::duration<Rep, Period>& timeout = std::chrono::seconds(5)) const {
            
            auto future = buildHexAsync();
            if (future.wait_for(timeout) == std::future_status::timeout) {
                throw std::runtime_error("Build hex operation timed out");
            }
            return future.get();
        }
    };

} // namespace DeviceCommons
